package com.kr.weitao.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.Iterator;

public class XML {
  public static final Character AMP = new Character('&');
  public static final Character APOS = new Character('\'');
  public static final Character BANG = new Character('!');
  public static final Character EQ = new Character('=');
  public static final Character GT = new Character('>');
  public static final Character LT = new Character('<');
  public static final Character QUEST = new Character('?');
  public static final Character QUOT = new Character('"');
  public static final Character SLASH = new Character('/');

  public static String escape(String string) {
    StringBuffer sb = new StringBuffer();
    int i = 0;
    for (int len = string.length(); i < len; i++) {
      char c = string.charAt(i);
      switch (c) {
        case '&':
          sb.append("&amp;");
          break;
        case '<':
          sb.append("&lt;");
          break;
        case '>':
          sb.append("&gt;");
          break;
        case '"':
          sb.append("&quot;");
          break;
        default:
          sb.append(c);
      }
    }
    return sb.toString();
  }

  private static boolean parse(XMLTokener x, JSONObject context, String name) {
    JSONObject o = null;
    JSONArray ja=new JSONArray();


    Object t = x.nextToken();
    if (t == BANG) {
      char c = x.next();
      if (c == '-') {
        if (x.next() == '-') {
          x.skipPast("-->");
          return false;
        }
        x.back();
      } else if (c == '[') {
        t = x.nextToken();
        if ((t.equals("CDATA")) && (x.next() == '[')) {
          String s = x.nextCDATA();
          if (s.length() > 0) {
            context.put("content", s);
          }
          return false;
        }
        return false;
      }
      int i = 1;
      do {
        t = x.nextMeta();
        if (t == null) {
          return false;
        }
        if (t == LT) {
          i++;
        } else if (t == GT) {
          i--;
        }
      } while (i > 0);
      return false;
    }
    if (t == QUEST) {
      x.skipPast("?>");
      return false;
    }
    if (t == SLASH) {
      t = x.nextToken();
      if (name == null) {
          return false;
      }
      if (!t.equals(name)) {
          return false;
      }
      if (x.nextToken() != GT) {
          return false;
      }
      return true;
    }
    if ((t instanceof Character)) {
        return false;
    }
    String n = (String) t;
    t = null;
    o = new JSONObject();

    for (; ; ) {
      if (t == null) {
        t = x.nextToken();
      }
      if (!(t instanceof String)) {
        break;
      }
      String s = (String) t;
      t = x.nextToken();
      if (t == EQ) {
        t = x.nextToken();
        if (!(t instanceof String)) {
          return false;
        }
        o.put(s, t);
        t = null;
      } else {
        o.put(s, "");
      }
    }
    if (t == SLASH) {
      if (x.nextToken() != GT) {
          return false;
      }
      context.put(n, o);
      return false;
    }
    if (t == GT) {
      do {
        for (; ; ) {
          t = x.nextContent();
          if (t == null) {
            if (n != null) {
                return false;
            }
            return false;
          }
          if (!(t instanceof String)) {
            break;
          }
          String s = (String) t;
          if (s.length() > 0) {
            o.put("content", s);
          }
        }
      } while ((t != LT) || (!parse(x, o, n)));
      if (o.size() == 0) {
        context.put(n, "");
      } else if ((o.size() == 1) && (o.get("content") != null)) {
        context.put(n, o.get("content"));
      } else {
        if(context.containsKey(n)){
          ja.add(o);
          context.put(n,ja);
        }else {
          context.put(n, o);
        }
      }
      return false;
    }
      return false;
  }

  public static JSONObject toJSONObject(String string) {
    JSONObject o = new JSONObject();
    XMLTokener x = new XMLTokener(string);
    while (x.more()) {
      x.skipPast("<");
      parse(x, o, null);
    }
    return o;
    /*        while ((x.more()) && (x.skipPast("<"))) {
        parse(x, o, null);
    }*/
  }

  public static String toString(Object o) {
    return toString(o, null);
  }

  public static String toString(Object o, String tagName)  {
    StringBuffer b = new StringBuffer();
    if ((o instanceof JSONObject)) {
      if (tagName != null) {
        b.append('<');
        b.append(tagName);
        b.append('>');
      }
      JSONObject jo = (JSONObject) o;
      Iterator keys = jo.entrySet().iterator();
      while (keys.hasNext()) {
        String k = keys.next().toString();
        Object v = jo.get(k);
        String s;
        //                String s;
        if ((v instanceof String)) {
          s = (String) v;
        } else {
          s = null;
        }
        if (k.equals("content")) {
          if ((v instanceof JSONArray)) {
            JSONArray ja = (JSONArray) v;
            int len = ja.size();
            for (int i = 0; i < len; i++) {
              if (i > 0) {
                b.append('\n');
              }
              b.append(escape(ja.get(i).toString()));
            }
          } else {
            b.append(escape(v.toString()));
          }
        } else if ((v instanceof JSONArray)) {
          JSONArray ja = (JSONArray) v;
          int len = ja.size();
          for (int i = 0; i < len; i++) {
            b.append(toString(ja.get(i), k));
          }
        } else if (v.equals("")) {
          b.append('<');
          b.append(k);
          b.append("/>");
        } else {
          b.append(toString(v, k));
        }
      }
      if (tagName != null) {
        b.append("</");
        b.append(tagName);
        b.append('>');
      }
      return b.toString();
    }
    if ((o instanceof JSONArray)) {
      JSONArray ja = (JSONArray) o;
      int len = ja.size();
      for (int i = 0; i < len; i++) {
        b.append(toString(ja.get(i), tagName == null ? "array" : tagName));
      }
      return b.toString();
    }
    String s = o == null ? "null" : escape(o.toString());
    return "<" + tagName + ">" + s + "</" + tagName + ">";
  }
}
